package com.damage.materiel_dept.service.impl;

import com.damage.common.config.OrderConfig;
import com.damage.common.config.PurchaseInvoiceConfig;
import com.damage.common.entity.*;
import com.damage.common.exception.IncorrectPriceException;
import com.damage.common.exception.IncorrectStateException;
import com.damage.common.service.IPublicService;
import com.damage.materiel_dept.mapper.IPurchaseInvoiceDetailMapper;
import com.damage.materiel_dept.mapper.IPurchaseInvoiceMapper;
import com.damage.materiel_dept.service.IPurchaseInvoiceService;
import com.google.common.collect.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Service
public class PurchaseInvoiceServiceImpl implements IPurchaseInvoiceService{

    @Autowired
    private IPurchaseInvoiceMapper purchaseInvoiceMapper;

    @Autowired
    private IPurchaseInvoiceDetailMapper purchaseInvoiceDetailMapper;

    @Autowired
    private IPublicService publicService;

    @Autowired
    private OrderConfig orderConfig;

    @Autowired
    PurchaseInvoiceConfig invoiceConfig;

    @Override
    @Transactional
    public Integer newPurchaseInvoice(PurchaseInvoice purchaseInvoice)
            throws IncorrectStateException,IncorrectPriceException{
        //获得对应订单的详细信息
        Integer orderId = purchaseInvoice.getOrderId();
        Order order = publicService.findOrderById(orderId);
        List<OrderDetail> orderDetails = publicService.findDetailByOrderId(orderId);
        order.setDetails(orderDetails);
        //检查订单状态，是否允许创建购货发票
        if (order.getState() != OrderConfig.DELIVERING){
            throw new IncorrectStateException("订单状态不是已出货，不能生成这个订单的购货发票！");
        }
        //检查购货发票的价格是否正确
        checkPirce(purchaseInvoice);
        //判断购货发票是否和订单一致
        Boolean isConsistent = checkConsistent(order, purchaseInvoice);
        if (isConsistent == true){
            purchaseInvoice.setIsConsistent(PurchaseInvoiceConfig.CONSISTENT);
        }else {
            purchaseInvoice.setIsConsistent(PurchaseInvoiceConfig.INCONSISTENT);
        }

        //插入购货发票
        purchaseInvoiceMapper.insert(purchaseInvoice);
        Integer purchaseInvoiceId = purchaseInvoice.getId();

        List<PurchaseInvoiceDetail> details = purchaseInvoice.getDetails();
        for (PurchaseInvoiceDetail detail : details) {
            detail.setPurchaseInvoiceId(purchaseInvoiceId);
        }
        //插入购货发票详情
        if (details != null){
            purchaseInvoiceDetailMapper.insertBatch(details);
        }
        //将生成了购货发票的订单状态置为已完成
        purchaseInvoiceMapper.finishOrder(orderId);

        return purchaseInvoiceId;
    }

    @Override
    public PurchaseInvoice findDetailedPurchaseInvoiceById(Integer purchaseInvoiceId) {
        PurchaseInvoice purchaseInvoice = purchaseInvoiceMapper.findById(purchaseInvoiceId);
        List<PurchaseInvoiceDetail> details = purchaseInvoiceDetailMapper.findByPurchaseInvoiceId(purchaseInvoiceId);
        purchaseInvoice.setDetails(details);
        return purchaseInvoice;
    }

    @Override
    public Integer setProcessInstanceId(Integer purchaseInvoiceId, String processInstanceId) {
        return purchaseInvoiceMapper.setProcessInstanceId(purchaseInvoiceId,processInstanceId);
    }

    @Override
    public PurchaseInvoice findById(Integer purchaseInvoiceId) {
        return purchaseInvoiceMapper.findById(purchaseInvoiceId);
    }

    private void checkPirce(PurchaseInvoice purchaseInvoice)throws IncorrectPriceException{
        //计算金额，用数据库最新的数据对前端传来的数据进行更新。
        List<PurchaseInvoiceDetail> details = purchaseInvoice.getDetails();
        Double totalPrice = 0d;
        for (PurchaseInvoiceDetail detail : details) {
            Integer supplyGoodId = detail.getSupplyGood().getId();
            SupplyGood supplyGood = publicService.findSupplyGoodById(supplyGoodId);

            //判断数据库的商品价格和前端传来的商品价格是否相等
            if (supplyGood.getPrice().doubleValue()
                    != detail.getSupplyGood().getPrice().doubleValue()) {
                throw new IncorrectPriceException("供应商品的价格和数据库的价格不一样!");
            }
            //判断数据库计算的详情价格和前端传来的详情的价格是否相等
            Double price = supplyGood.getPrice() * detail.getCount();
            if (price.doubleValue()
                    != detail.getPrice().doubleValue()) {
                throw new IncorrectPriceException("购货发票详情的价格和数据库计算的价格不一样!");
            }
            totalPrice += price;
        }

        //判断后端计算的总价是否和前端传来的数据相同
        if (totalPrice.doubleValue()
                != purchaseInvoice.getTotalPrice().doubleValue()) {
            throw new IncorrectPriceException("购货发票的总价和数据库计算的结果不一样!");
        }
    };

    private Boolean checkConsistent(Order order,PurchaseInvoice purchaseInvoice){
        Boolean isConsistent = true;
        List<OrderDetail> orderDetails = order.getDetails();
        List<PurchaseInvoiceDetail> purchaseInvoiceDetails = purchaseInvoice.getDetails();
        for (OrderDetail orderDetail: orderDetails) {
            for (PurchaseInvoiceDetail purchaseInvoiceDetail: purchaseInvoiceDetails) {
                if (orderDetail.getSupplyGood().getId() == purchaseInvoiceDetail.getSupplyGood().getId()
                        && orderDetail.getCount() == purchaseInvoiceDetail.getCount()){
                    //如果订单中供应商品的编号和数量和购货发票的一样，则是一致的
                    break;
                }
                //订单和购货发票不一致
                isConsistent = false;
            }
            if (isConsistent == false){
                //出现过一次订单与购货发票不一致
                return false;
            }
        }
        return true;
    }
}
